package com.ws.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;


/** <br>
 * 标题: json工具类<br>
 * 描述: 将javaBean转json字符串，将json字符串转java对象<br>
 *
 */
public class JsonUtils {

	public static ObjectMapper objectMapper = new ObjectMapper();

	private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);

	/** 使用泛型方法，把json字符串转换为相应的JavaBean对象。 (1)转换为普通JavaBean：readValue(json,Student.class) (2)转换为List,如List<Student>,将第二个参数传递为Student
	 * [].class.然后使用Arrays.asList();方法把得到的数组转换为特定类型的List
	 * 
	 * @param content
	 * @param valueType
	 * @return */
	public static <T> T jsonStringToJavaBean(String content, Class<T> valueType) {

		if (valueType == null) {
			return null;
		}

		if (content == null) {
			return null;
		}

		try {
			objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
			return objectMapper.readValue(content, valueType);
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("将字符串转Java对象错误，请检查转换类型");
			//throw new Exception("C994", "将字符串转Java对象错误，请检查转换类型", e);
		}
		//return null;
	}
	/**
	 *
	 * @param jsonStr
	 * @param clazz
	 * @return 将json 数组转换 为 List<Object>
	 */
	public static <T> T jsonStringToListJavaBean(String jsonStr, Class clazz) {

		try {
			JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, clazz);
			return objectMapper.readValue(jsonStr, javaType);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	/** json数组转List
	 * 
	 * @param jsonStr
	 * @param valueTypeRef
	 * @return */
	public static <T> T jsonStringToJavaBean(String jsonStr, TypeReference<T> valueTypeRef) {
		if (valueTypeRef == null) {
			return null;
		}
		if (jsonStr == null) {
			return null;
		}
		try {
			objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
			return objectMapper.readValue(jsonStr, valueTypeRef);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	
	
	/** json数组转List
	 * 
	 * @param jsonStr
	 * @param javatype
	 * @return */
	public static <T> T jsonStringToListJavaBean(String jsonStr, JavaType javatype) {

		try {
			return objectMapper.readValue(jsonStr, javatype);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/** 把JavaBean转换为json字符串
	 * 
	 * @param object
	 * @return */
	public static String objectBeanToJsonString(Object object){
		String taskContent = null;
		try {
			if (object == null) {
				taskContent = "";
			}
			else {
				taskContent = objectMapper.writeValueAsString(object);
			}
		}
		catch (JsonProcessingException e) {
			log.error("将对象生成json异常，请检查该对象！", e);
			//throw new ResourceException("C991", "对象生成json异常，请检查该对象！", e);
		}
		return taskContent;
	}
	/** 把JavaBean转换为json字符串 排除掉null字段
	 *
	 * @param object
	 * @return */
	public static String objectBeanToJsonStringExcludeNull(Object object) {
		String taskContent = null;
		ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		try {
			if (object == null) {
				taskContent = "";
			}
			else {
				taskContent = objectMapper.writeValueAsString(object);
			}
		}
		catch (JsonProcessingException e) {
			log.error("将对象生成json异常，请检查该对象！", e);
			//throw new ResourceException("C991", "对象生成json异常，请检查该对象！", e);
		}

		return taskContent;
	}
	
	/** 获取泛型的Collection Type
	 * 
	 * @param collectionClass
	 *        泛型的Collection
	 * @param elementClasses
	 *        元素类
	 * @return JavaType Java类型
	 * @since 1.0 */
	public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
		return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
	}

}

